import { computed } from 'vue'
import { useMainStore } from "@/store/main"
import { useSlidesStore } from "@/store/slides"
import { storeToRefs } from "pinia"
import useHistorySnapshot from "./useHistorySnapshot"
import { PPTElement } from '@/types/slides'
import { nanoid } from 'nanoid'

export default () => {
  const mainStore = useMainStore()
  const slideStore = useSlidesStore()
  const { activeElementIdList, activeElementList, handleElementId } = storeToRefs(mainStore)
  const { currentSlide } = storeToRefs(slideStore)
  const { addHistorySnapshot } = useHistorySnapshot()

  // 判断当前选中的元素是否可以组合
  const canCombine = computed(() => {
    // 选中的元素只有一个，不可组合
    if (activeElementList.value.length < 2) return false

    // 选中的元素中，第一个元素有groupId，不可组合
    const firstGroupId = activeElementList.value[0].groupId
    if (!firstGroupId) return true

    // 选中的元素中，所有的groupId是否都相同，都相同则不可组合
    const inSameGroup = activeElementList.value.every(el => (el.groupId && el.groupId) === firstGroupId)
    return !inSameGroup
  })

  // 组合当前选中的元素：给当前选中的元素赋予一个相同的分组ID
  const combineElements = () => {
    if (!activeElementList.value.length) return

    // 生成一个新元素列表进行后续操作
    let newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))

    // 生成分组ID
    const groupId = nanoid(10)

    // 收集需要组合的元素列表，并赋上唯一分组ID
    const combineElementList: PPTElement[] = []
    for (const el of newElementList) {
      if (activeElementIdList.value.includes(el.id)) {
        el.groupId = groupId
        combineElementList.push(el)
      }
    }

    /**
     * 确保该组合内所有元素成员的层级是连续的，具体操作为：
     * 1. 先获取到该组合内最上层元素的层级
     * 2. 将本次需要组合的元素从新元素列表中移除
     * 3. 根据最上层元素的层级位置，将需要组合的元素列表一起插入到新元素列表中合适的位置
     */
    const combineElementMaxLevel = newElementList.findIndex(_el => _el.id === combineElementList[combineElementList.length - 1].id)
    const combineElementIdList = combineElementList.map(_el => _el.id)
    newElementList = newElementList.filter(_el => !combineElementIdList.includes(_el.id))

    const insertLevel = combineElementMaxLevel - combineElementList.length + 1
    newElementList.splice(insertLevel, 0, ...combineElementList)

    slideStore.updateSlide({ elements: newElementList })
    addHistorySnapshot()
  }

  // 取消元素组合：移除选中元素的分组ID
  const unCombineElements = () => {
    if (!activeElementList.value.length) return
    // some()：有一个元素满足条件，则表达式返回true , 剩余的元素不会再执行检测
    const hasElementInGroup = activeElementList.value.some(item => item.groupId)
    if (!hasElementInGroup) return

    const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
    for (const el of newElementList) {
      // 元素被选中以及元素有groupId
      if (activeElementIdList.value.includes(el.id) && el.groupId) delete el.groupId
    }
    slideStore.updateSlide({ elements: newElementList })

    // 取消组合后，需要重置激活元素状态，默认重置为当前正在操作的元素，若不存在则重置为空
    const handleElementIdList = handleElementId.value ? [handleElementId.value] : []
    mainStore.setActiveElementIdList(handleElementIdList)
    addHistorySnapshot()
  }


  return {
    canCombine,
    combineElements,
    unCombineElements
  }
}